package com.acmen.easyapi.validation;

import com.acmen.easyapi.annotation.ReqParam;
import com.acmen.easyapi.enums.BasicCode;
import com.acmen.easyapi.model.Response;
import com.acmen.easyapi.provider.DictionaryProvider;
import com.acmen.easyapi.strategy.ReqParamStrategy;
import com.acmen.easyapi.util.ClassUtil;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;


/**
 * 校验器
 *
 * @author acmen
 * @date 2022-03-08
 */
@Component
public class SchemaValidator extends AbstractValidator{
    @Resource
    private ReqParamStrategy reqParamStrategy;
    @Resource
    private DictionaryProvider dictionaryProvider;

    public Response validate(Object[] args, ReqParam[] reqParams) {
        List<Message> messages = new ArrayList<Message>();
        for (int i = 0; i < args.length; i++) {
            Object data = args[i];
            if(reqParams==null || reqParams.length-1<i){
                if (!ClassUtil.isBasicType(data.getClass())) {
                    messages.addAll(validate(data));
                }
            }else{
                ReqParam reqParam = reqParams[i];
                if (reqParam == null) {
                    if (!ClassUtil.isBasicType(data.getClass())) {
                        messages.addAll(validate(data));
                    }
                } else {
                    messages.addAll(validate(data, reqParam, reqParam.label()));
                }
            }
        }
        if(messages.isEmpty()){
            return Response.success();
        }else{
            return buildFailureResponse(messages);
        }
    }


    protected List<Message> validate(Object data, String fieldNamePrefix) {
        List<Message> messages = new ArrayList<Message>();
        List<Field> fields = ClassUtil.getFields(data.getClass());
        for (Field field : fields) {
            ReqParam reqParam = reqParamStrategy.getReqParam(data.getClass(),field);
            if (reqParam == null) {
                continue;
            }
            String fieldName = field.getName();
            if (fieldNamePrefix != null) {
                fieldName = fieldNamePrefix + "." + fieldName;
            }
            Object fieldValue = ClassUtil.getFieldValue(data, field);
            messages.addAll(validate(fieldValue, reqParam, fieldName));
        }
        // 校验必录组
        validateRequireGroup(data, fields, fieldNamePrefix, messages);
        return messages;
    }


    /**
     * 创建异常回应
     *
     * @param messages
     * @return
     */
    public static Response buildFailureResponse(List<Message> messages) {
        String errorMsg = buildFailureMessage(messages);
        return Response.failure(BasicCode.PARAM_VALIDATE_ERROR.getCode(),errorMsg);
    }
}
